/*
 *
 * This class contain functions that take as input collection and return 
 *  a different collection that collapses all its elements. The detection will
 *  collapse all objects deriving from Collection and put children elements into
 *  the returning collection. Detection is recursive, so flattening a collection
 *  of collection of collection will result in a collection of non-collections.
 */
package org.yagnus.langutils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.TreeSet;

/**
 *
 * @author hc.busy
 */
public final class Flattener {

    // By default put content of sub collection in the place where the collection is.
    public static final void flatten(final Collection in, final Collection out){
        flatten(in,out,true);
    }
    
    public static final void flatten(final Collection in, final Collection out, final boolean prefix) {

        final LinkedList<Collection> todo = new LinkedList<Collection>();
        todo.add(in);

        while (!todo.isEmpty()) {
            Collection c = todo.pop();
            for (Object o : c) {
                if (o instanceof Collection) {
                    if (prefix) {
                        todo.push((Collection)o);
                    } else {
                        todo.add((Collection) o);
                    }
                } else {
                    out.add(o);
                }
            }
        }
    }

    public static final ArrayList flatten(final ArrayList in) {
        final ArrayList ret = new ArrayList();
        flatten(in, ret);
        return ret;
    }

    public static final LinkedList flatten(final LinkedList in) {
        final LinkedList ret = new LinkedList();
        flatten(in, ret);
        return ret;
    }

    public static final HashSet flatten(final HashSet in) {
        final HashSet ret = new HashSet();
        flatten(in, ret, false);
        return ret;
    }

    public static final TreeSet flatten(final TreeSet in) {
        final TreeSet ret = new TreeSet();
        flatten(in, ret, false);
        return ret;
    }

}
